/*
 * All rights Reserved, Designed By Rylynn
 * @ClassName:  HeteroGraph
 * @Description:
 * @author: rylynn
 * @date:   2021/7/9
 *
 */

package org.etnetwork.core;

import com.google.common.base.Preconditions;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

public class HeteroGraph extends AbstractGraph{
    private Graph graph;

    public HeteroGraph() {
        graph = new Graph();
    }

    public HeteroGraph addVertex(Vertex vertex, String type) {
        vertex.getProperties().put("type", type);
        graph.addVertex(vertex);
        return this;
    }

    @Override
    public HeteroGraph addVertex(Vertex vertex) {
        Preconditions.checkArgument(vertex.getProperties().get("type") != null, "The value of type can't be null in vertex properties");
        graph.addVertex(vertex);
        return this;
    }

    @Override
    public HeteroGraph addEdge(Edge edge) {
        return this;
    }

    @Override
    public HeteroGraph addVertices(Vertex... vertices) {
        Arrays.stream(vertices).forEach(this::addVertex);
        return this;
    }

    @Override
    public HeteroGraph addEdges(Edge... edges) {
        return this;
    }

    @Override
    public HeteroGraph deleteVertex(Vertex vertex) {
        return this;
    }

    @Override
    public HeteroGraph deleteEdge(Edge edge) {
        this.graph.deleteEdge(edge);
        return this;
    }

    @Override
    public HeteroGraph deleteEdgeFrom(Long sourceId) {
        this.graph.deleteEdgeFrom(sourceId);
        return this;
    }

    @Override
    public HeteroGraph deleteEdgeTo(Long targetId) {
        this.graph.deleteEdgeTo(targetId);
        return this;
    }

    @Override
    public HeteroGraph deleteVertices(Vertex... vertices) {
        this.graph.deleteVertices(vertices);
        return this;
    }

    @Override
    public HeteroGraph deleteEdges(Edge... edges) {
        this.graph.deleteEdges(edges);
        return this;
    }

    public List<Vertex> getVertex(String type) {
        return this.graph.getVertices().stream().
                filter(vertex -> vertex.getProperties().get("type") == type).
                collect(Collectors.toList());
    }

    @Override
    public Optional<Vertex> getVertex(Long id) {
        return this.graph.getVertex(id);
    }

    @Override
    public Optional<Vertex> getEdge(Long source, Long target) {
        return this.graph.getEdge(source, target);
    }

    @Override
    public List<Vertex> getVertices() {
        return null;
    }

    @Override
    public List<Edge> getEdges() {
        return null;
    }

    @Override
    public List<Vertex> getVertices(Map<String, Object> properties) {
        return null;
    }

    @Override
    public List<Edge> getEdges(Map<String, Object> properties) {
        return null;
    }

    @Override
    public Optional<Vertex> hasVertex(Long vertexId) {
        return Optional.empty();
    }

    @Override
    public Optional<Edge> hasEdge(Long sourceId, Long targetId) {
        return Optional.empty();
    }

    @Override
    public Integer getEdgesNumber() {
        return 0;
    }

    @Override
    public Integer getVerticesNumber() {
        return 0;
    }
}
